﻿using Tszy.Unlimited.Base.Exceptions;

namespace Tszy.Unlimited.Base.Common;

/// <summary>
/// 验证。
/// </summary>
public static class Check
{
    /// <summary>
    /// 判断 value 是否为 True，如果不是，则抛出异常。
    /// </summary>
    /// <param name="value"></param>
    /// <param name="errorMessage">错误信息。</param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void IsTrue(bool value, string errorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (value)
            return;

        throw new MainApplicationException(errorCode, errorMessage, innerException);
    }

    /// <summary>
    /// 判断 value 是否为 True，如果不是，则抛出异常。
    /// </summary>
    /// <param name="value"></param>
    /// <param name="createErrorMessage"></param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void IsTrue(bool value, Func<string> createErrorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (value)
            return;

        if (createErrorMessage == null)
            return;

        var errorMessage = createErrorMessage();

        throw new MainApplicationException(errorCode, errorMessage, innerException);
    }

    /// <summary>
    /// 判断 value 是否为 True，如果不是，则抛出异常。
    /// </summary>
    /// <typeparam name="TException">异常类型。</typeparam>
    /// <param name="value"></param>
    /// <param name="exceptionCreator">创建异常信息。</param>
    public static void IsTrue<TException>(bool value, Func<TException> exceptionCreator) where TException : Exception
    {
        if (value)
            return;

        if (exceptionCreator == null)
            return;

        throw exceptionCreator();
    }

    /// <summary>
    /// 判断 value 是否为 False，如果不是，则抛出异常。
    /// </summary>
    /// <param name="value"></param>
    /// <param name="errorMessage"></param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void IsFalse(bool value, string errorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (!value)
            return;

        throw new MainApplicationException(errorCode, errorMessage, innerException);
    }

    /// <summary>
    /// 判断 value 是否为 False，如果不是，则抛出异常。
    /// </summary>
    /// <param name="value"></param>
    /// <param name="createErrorMessage"></param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void IsFalse(bool value, Func<string> createErrorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (!value)
            return;

        if (createErrorMessage == null)
            return;

        var errorMessage = createErrorMessage();

        throw new MainApplicationException(errorCode, errorMessage, innerException);
    }

    /// <summary>
    /// 判断 value 是否为 False，如果不是，则抛出异常。
    /// </summary>
    /// <typeparam name="TException">异常类型。</typeparam>
    /// <param name="value"></param>
    /// <param name="exceptionCreator">创建异常信息。</param>
    public static void IsFalse<TException>(bool value, Func<TException> exceptionCreator) where TException : Exception
    {
        if (!value)
            return;

        if (exceptionCreator == null)
            return;

        throw exceptionCreator();
    }

    /// <summary>
    /// 验证对象不为 null。
    /// </summary>
    /// <typeparam name="T">验证对象的类型。</typeparam>
    /// <param name="value">验证对象。</param>
    /// <param name="errorMessage">异常信息。</param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void NotNull<T>(T value, string errorMessage, int errorCode = 0, Exception? innerException = null) where T : class
    {
        if (value == null)
        {
            throw new MainApplicationException(errorCode, errorMessage, innerException);
        }
    }

    /// <summary>
    /// 验证对象不为 null。
    /// </summary>
    /// <typeparam name="T">验证对象的类型。</typeparam>
    /// <param name="value">验证对象。</param>
    /// <param name="createErrorMessage">异常信息。</param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void NotNull<T>(T value, Func<string> createErrorMessage, int errorCode = 0, Exception? innerException = null) where T : class
    {
        if (value == null)
        {
            if (createErrorMessage == null)
                return;

            var errorMessage = createErrorMessage();

            throw new MainApplicationException(errorCode, errorMessage, innerException);
        }
    }

    /// <summary>
    /// 验证对象不为 null。
    /// </summary>
    /// <typeparam name="T">验证对象的类型。</typeparam>
    /// <param name="value">验证对象。</param>
    /// <param name="exceptionCreator">创建异常信息。</param>
    public static void NotNull<T>(T value, Func<Exception> exceptionCreator) where T : class
    {
        if (value == null)
        {
            if (exceptionCreator == null)
                return;

            throw exceptionCreator();
        }
    }

    /// <summary>
    /// 验证字符串不是 null、空字符串和空白字符串中的一个。
    /// </summary>
    /// <param name="value">要验证的字符串。</param>
    /// <param name="errorMessage">异常信息。</param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void NotEmpty(string value, string errorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new MainApplicationException(errorCode, errorMessage, innerException);
        }
    }

    /// <summary>
    /// 验证字符串不是 null、空字符串和空白字符串中的一个。
    /// </summary>
    /// <param name="value">要验证的字符串。</param>
    /// <param name="createErrorMessage">异常信息。</param>
    /// <param name="errorCode">错误码。</param>
    /// <param name="innerException">子异常。</param>
    public static void NotEmpty(string value, Func<string> createErrorMessage, int errorCode = 0, Exception? innerException = null)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            if (createErrorMessage == null)
                return;

            var errorMessage = createErrorMessage();

            throw new MainApplicationException(errorCode, errorMessage, innerException);
        }
    }

    /// <summary>
    /// 验证字符串不是 null、空字符串和空白字符串中的一个。
    /// </summary>
    /// <param name="value">要验证的字符串。</param>
    /// <param name="exceptionCreator">创建异常信息。</param>
    /// <returns>要验证的字符串。</returns>
    public static void NotEmpty<TException>(string value, Func<TException> exceptionCreator) where TException : Exception
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            if (exceptionCreator == null)
                return;

            throw exceptionCreator();
        }
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static int OutOfRange(int value, string parameterName, int min = int.MinValue, int max = int.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static decimal OutOfRange(decimal value, string parameterName, decimal min = decimal.MinValue, decimal max = decimal.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static long OutOfRange(long value, string parameterName, long min = long.MinValue, long max = long.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static float OutOfRange(float value, string parameterName, float min = float.MinValue, float max = float.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static double OutOfRange(double value, string parameterName, double min = double.MinValue, double max = double.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }

    /// <summary>
    /// 验证指定的数值是否超出定义的范围。
    /// </summary>
    /// <param name="value">数值。</param>
    /// <param name="parameterName">参数名。</param>
    /// <param name="min">允许的最小值（含当前值）。</param>
    /// <param name="max">允许的最大值（含当前值）。</param>
    /// <param name="message">错误消息。</param>
    /// <returns>数值。</returns>
    public static short OutOfRange(short value, string parameterName, short min = short.MinValue, short max = short.MaxValue, string message = "")
    {
        if (value >= min && value <= max)
        {
            return value;
        }

        if (string.IsNullOrWhiteSpace(message))
            throw new ArgumentOutOfRangeException(parameterName);

        throw new ArgumentOutOfRangeException(parameterName, value, message);
    }
}
